<?
require_once 'PHPUnit/Framework.php';

use pmvc\aop\ProxyUtil;
use pmvc\aop\MethodInterceptor;

class SomeClass {
	public $value;
}

interface BasicInterface {
	function sayHello();
	function sayHelloAgain();
	function doEcho($theMessage);
	function what(SomeClass $class);
}

interface BasicInterface2
	extends BasicInterface {
	function subClassHello();
}

interface SomeOtherInterface {
	function fart();
}

class TestInterceptor
	implements MethodInterceptor {

	public function methodInvoked($object, $methodName, &$args, $userData=NULL) {
		switch($methodName) {
			case "sayHello": return "hello";
			case "sayHelloAgain": return "hello again";
			case "doEcho": return $args[0];
			case "what": return $args[0]->value;
			case "subClassHello": return "Hello there";
			case "fart": return "stinky";
			default: throw Exception("Unknown methodname");
		}
	}
		
}

class ProxyUtilTest
	extends PHPUnit_Framework_TestCase {

	public function testDynamicProxy() {
		$instance = ProxyUtil::dynamicProxy(new TestInterceptor(), NULL, Array('BasicInterface2', 'pmvc\ioc\ObjectFactory', 'SomeOtherInterface'));
		$this->assertTrue(ProxyUtil::isProxy($instance));
		$this->assertNull(ProxyUtil::getProxiedObject($instance));
		$this->assertNotNull($instance);
		$this->assertEquals("hello", $instance->sayHello());
		$this->assertEquals("Hello there", $instance->subClassHello());
		$this->assertEquals("hello again", $instance->sayHelloAgain());
		$this->assertEquals("Howdy", $instance->doEcho("Howdy"));
		$this->assertEquals("stinky", $instance->fart());
		$v = new SomeClass();
		$v->value = "works";
		$this->assertEquals($v->value, $instance->what($v));
	}

	public function testDynamicProxyWithObject() {
		$object = new SomeClass();
		$instance = ProxyUtil::dynamicProxy(new TestInterceptor(), NULL, Array('BasicInterface2', 'pmvc\ioc\ObjectFactory', 'SomeOtherInterface', 'SomeOtherInterface'), $object);
		$this->assertTrue(ProxyUtil::isProxy($instance));
		$this->assertEquals($object, ProxyUtil::getProxiedObject($instance));
		$this->assertNotNull($instance);
		$this->assertEquals("hello", $instance->sayHello());
		$this->assertEquals("Hello there", $instance->subClassHello());
		$this->assertEquals("hello again", $instance->sayHelloAgain());
		$this->assertEquals("Howdy", $instance->doEcho("Howdy"));
		$this->assertEquals("stinky", $instance->fart());
		$v = new SomeClass();
		$v->value = "works";
		$this->assertEquals($v->value, $instance->what($v));
	}

}

?>